luachipTransfer = {}
lcTrans = luachipTransfer
local ws = luachipTransfer

ws.tickrate = 10 //Ticks per second
ws.packetsize = 230 //Bytes per packet
ws.stack = {}

function ws.send(transferID,cmd,dat)
	ws.stack[transferID] = {
		dat = dat,
		open = false,
		cmd = cmd,
	}
end

function ws.stat(transferID)
	local dat = ws.stack[transferID]
	if not dat then
		return
	end
	
	if dat.open then
		//Percentage,Seconds left
		return (dat.next-1)/dat.qty,(dat.qty-dat.next+2)/ws.tickrate
	else
		return false
	end
end

ws.next = CurTime()+1/ws.tickrate
ws.curTrans = nil
function ws.think()
	if ws.next < CurTime() then
		
		//Select a transfer
		if not ws.curTrans then
			for k,v in pairs(ws.stack) do
				ws.curTrans = k
				break
			end
		end
		
		if ws.curTrans then
			local dat = ws.stack[ws.curTrans]
			if dat.open then
				if dat.stack[dat.next] then
					//Send
					RunConsoleCommand("lc",tostring(dat.stack[dat.next]))
					dat.next = dat.next+1
				elseif dat.next > dat.qty then
					//Close
					RunConsoleCommand("lci","close",dat.cmd)
					ws.stack[ws.curTrans] = nil
					ws.curTrans = nil
				end
			else
				//Break up the data
				dat.stack = {}
				dat.dat = dat.dat:gsub("\n",",.:nl:.,")
				for i = 1,#dat.dat,ws.packetsize do
					table.insert(dat.stack,dat.dat:sub(1,ws.packetsize))
					dat.dat = dat.dat:sub(ws.packetsize+1)
				end
				
				PrintTable(dat.stack)
				dat.qty = #dat.stack
				dat.next = 1
				dat.open = true
				
				RunConsoleCommand("lci","open",tostring(#dat.stack))
			end
		end
		
		ws.next = CurTime()+1/ws.tickrate
	end
end

hook.Add("Think","luachipTransfer.think",ws.think)

ws.cmd = {}

ws.recvbuff = nil
ws.recvqty = nil
ws.recvtickrate = 20
ws.recv = function(um)
	local str = um:ReadString()
	
	if ws.recvbuff then
		table.insert(ws.recvbuff,str)
	end
end

ws.recvi = function(um)
	local type = um:ReadChar()
	if type == 1 then
		local qty = um:ReadLong()
		ws.recvbuff = {}
		ws.recvqty = qty
		ws.recvtickrate = um:ReadShort()
	elseif type == 2 then
		if #ws.recvbuff == ws.recvqty then
			local out = ""
			for k,v in pairs(ws.recvbuff) do
				out = out..v
			end
			out = out:gsub(",.:nl:.,","\n")
			
			local cmd = um:ReadString()
			
			Msg(out,"\n")
			if ws.cmd[cmd] then
				ws.cmd[cmd](out)
			end
			
			ws.recvbuff = nil
			ws.recvqty = nil
		end
	end
end

function ws.setCommandFunction(command,f)
	ws.cmd[command] = f
end

function ws.statDownload()
	if ws.recvbuff then
		//Percentage,Seconds left
		return (#ws.recvbuff)/ws.recvqty,(ws.recvqty-#ws.recvbuff+1)/ws.recvtickrate
	else
		return false
	end
end

usermessage.Hook("lc",ws.recv)
usermessage.Hook("lci",ws.recvi)






